/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.logiclander.adhocracy.jira.cli;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Predicates.isNull;
import static com.google.common.base.Predicates.notNull;
import com.logiclander.adhocracy.cli.CommandLineReactor;
import com.logiclander.adhocracy.cli.CommandLineReactorTransactionCallback;
import com.logiclander.adhocracy.cli.CommandLineStatus;
import java.util.concurrent.Callable;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.support.TransactionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author tim
 */
public class JiraCliLifecycle implements Callable<CommandLineStatus> {

    private CommandLineReactor reactor;
    private TransactionTemplate txnTmplt;
    private boolean doInTxn = false;
    private CommandLineStatus currentStatus = CommandLineStatus.STOPPED;
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final ApplicationContext springContext;

    public JiraCliLifecycle(ApplicationContext context) {
        checkArgument(notNull().apply(context), "springContext cannot be null");
        this.springContext=context;
    }
    
    public void init() {
        checkState(notNull().apply(reactor), "reactor property not set");
    }

    @Override
    public CommandLineStatus call() {
        currentStatus = CommandLineStatus.RUNNING;
        RuntimeException caught=null;
        try {
            if(doInTxn){
                transaction();
            } else {
                execute();
            }
        } catch (RuntimeException ex) {
            caught = ex;
        } finally {
            if(isNull().apply(caught)) {
                currentStatus = CommandLineStatus.SUCCESS;
            } else {
                currentStatus = CommandLineStatus.FAIL;
                if(logger.isErrorEnabled()) {
                    logger.error("failure", caught);
                }
            }
        }
        return currentStatus;
    }
    
    private void execute() {
        reactor.init();
        reactor.process();
        reactor.destroy();
    }
    
    private void transaction() {
        CommandLineReactorTransactionCallback rtc = new CommandLineReactorTransactionCallback();
        rtc.setCommandLineReactor(reactor);
        txnTmplt.execute(rtc);
    }
    
    public void setCommandLineReactor(CommandLineReactor r) {
        checkState(isNull().apply(this.reactor), "reactor property already set");
        this.reactor = r;
    }
    
    public void setTransactionTemplate(TransactionTemplate t) {
        checkState(isNull().apply(this.txnTmplt), "transaction template already set");
    }

//?    
//    public String getTransactionTemplate() {
//        return (String) springContext.getBean("transactionTemplate");
//    }

    
}
